package com.freexiaoyu.cloud.utils

import android.annotation.SuppressLint
import android.text.TextUtils
import android.util.Log
import okhttp3.internal.and
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.io.InputStream
import java.util.*

/**
 * Created by DIY on 2017/5/4. 14:37
 * author:free宇
 * email:freexiaoyu@foxmail.com
 * describe:
 */
object FileTypeUtil {
    private const val TAG = "XtomFileTypeUtil"
    val FILE_TYPE_MAP: MutableMap<String, String> = HashMap()

    // JPEG (jpg)
    // PNG (png)
    // GIF (gif)
    // TIFF (tif)
    // Windows Bitmap (bmp)
    // CAD (dwg)
    // HTML (html)
    // Rich Text Format (rtf)
    // Photoshop (psd)
    // Email
    // Outlook Express(dbx)
    // Outlook (pst)
    // MS Word
    // MS Excel 注意：word 和 excel的文件头一样
    // MS Access (mdb)
    // WordPerfect (wpd)
    // Adobe Acrobat (pdf)
    // Quicken (qdf)
    // Windows Password (pwl)
    // Wave (wav)
    // Real Audio (ram)
    // Real Media (rm)
    //
    // Quicktime (mov)
    // Windows Media (asf)
    // MIDI (mid)
    val allFileType: Unit
         get() {
            FILE_TYPE_MAP["jpg"] = "FFD8FF" // JPEG (jpg)
            FILE_TYPE_MAP["png"] = "89504E47" // PNG (png)
            FILE_TYPE_MAP["gif"] = "47494638" // GIF (gif)
            FILE_TYPE_MAP["tif"] = "49492A00" // TIFF (tif)
            FILE_TYPE_MAP["bmp"] = "424D" // Windows Bitmap (bmp)
            FILE_TYPE_MAP["dwg"] = "41433130" // CAD (dwg)
            FILE_TYPE_MAP["html"] = "68746D6C3E" // HTML (html)
            FILE_TYPE_MAP["rtf"] = "7B5C727466" // Rich Text Format (rtf)
            FILE_TYPE_MAP["xml"] = "3C3F786D6C"
            FILE_TYPE_MAP["zip"] = "504B0304"
            FILE_TYPE_MAP["rar"] = "52617221"
            FILE_TYPE_MAP["psd"] = "38425053" // Photoshop (psd)
            FILE_TYPE_MAP["eml"] = "44656C69766572792D646174653A" // Email
            FILE_TYPE_MAP["dbx"] = "CFAD12FEC5FD746F" // Outlook Express(dbx)
            FILE_TYPE_MAP["pst"] = "2142444E" // Outlook (pst)
            FILE_TYPE_MAP["xls"] = "D0CF11E0" // MS Word
            FILE_TYPE_MAP["doc"] = "D0CF11E0" // MS Excel 注意：word 和 excel的文件头一样
            FILE_TYPE_MAP["mdb"] = "5374616E64617264204A" // MS Access (mdb)
            FILE_TYPE_MAP["wpd"] = "FF575043" // WordPerfect (wpd)
            FILE_TYPE_MAP["eps"] = "252150532D41646F6265"
            FILE_TYPE_MAP["ps"] = "252150532D41646F6265"
            FILE_TYPE_MAP["pdf"] = "255044462D312E" // Adobe Acrobat (pdf)
            FILE_TYPE_MAP["qdf"] = "AC9EBD8F" // Quicken (qdf)
            FILE_TYPE_MAP["pwl"] = "E3828596" // Windows Password (pwl)
            FILE_TYPE_MAP["wav"] = "57415645" // Wave (wav)
            FILE_TYPE_MAP["avi"] = "41564920"
            FILE_TYPE_MAP["ram"] = "2E7261FD" // Real Audio (ram)
            FILE_TYPE_MAP["rm"] = "2E524D46" // Real Media (rm)
            FILE_TYPE_MAP["mpg"] = "000001BA" //
            FILE_TYPE_MAP["mov"] = "6D6F6F76" // Quicktime (mov)
            FILE_TYPE_MAP["asf"] = "3026B2758E66CF11" // Windows Media (asf)
            FILE_TYPE_MAP["mid"] = "4D546864" // MIDI (mid)
        }

    /**
     * 获取文件类型
     *
     * @param path
     * 文件路径
     * @return String
     */
    fun getFileTypeByPath(path: String): String? {
        val file = File(path)
        val type = getFileTypeByFile(file)
        if (TextUtils.isEmpty(type)) {
            val dot = path.lastIndexOf('.')
            if (dot != -1) {
                return path.substring(dot + 1)
            }
        }
        return type
    }

    private fun getFileTypeByFile(file: File): String? {
        var `is`: InputStream? = null
        return try {
            val b = ByteArray(50)
            `is` = FileInputStream(file)
            `is`.read(b)
            getFileTypeByStream(b)
        } catch (e: IOException) {
            null
        } finally {
            if (`is` != null) try {
                `is`.close()
            } catch (e: IOException) {
                Log.i(TAG, "getFileTypeByFile异常92行")
                e.printStackTrace()
            }
        }
    }

    @SuppressLint("DefaultLocale")
    private fun getFileTypeByStream(b: ByteArray): String? {
        if (getFileHexString(b) == null) return null
        val filetypeHex = getFileHexString(b).toString()
        val entryiterator: Iterator<Map.Entry<String, String>> = FILE_TYPE_MAP
            .entries.iterator()
        while (entryiterator.hasNext()) {
            val entry = entryiterator.next()
            val fileTypeHexValue = entry.value
            if (filetypeHex.toUpperCase().startsWith(fileTypeHexValue)) {
                return entry.key
            }
        }
        return null
    }

    private fun getFileHexString(b: ByteArray?): String? {
        val stringBuilder = StringBuilder()
        if (b == null || b.size <= 0) {
            return null
        }
        for (i in b.indices) {
            val v: Int = b[i] and 0xFF
            val hv = Integer.toHexString(v)
            if (hv.length < 2) {
                stringBuilder.append(0)
            }
            stringBuilder.append(hv)
        }
        return stringBuilder.toString()
    }

    init {
        allFileType // 初始化文件类型信息
    }
}